#!/usr/bin/env python


# This is only needed for Python v2 but is harmless for Python v3.
import sip
sip.setapi('QString', 2)
sip.setapi('QVariant', 2)

from PyQt4 import QtCore, QtGui
import sys
import traceback


from reportlab.lib.units import cm
import reportlab.lib.pagesizes as pagesizes

import layout
import fb2parser

__builtins__.pagesizes = pagesizes
__builtins__.cm = cm
__builtins__.Default = layout.DefaultConfig

def myunichr(i):
    return unichr(i).encode('utf-8')

global oldchr

def printt(fb2in, pdfout, cfgf):
    cfg = __import__(cfgf)

    ## HACK FIX for bug in reportlab.lib.xmllib
    oldchr = chr
    __builtins__.chr = myunichr

    try:
        meta, body, binaries = fb2parser.parse(fb2in, cfg.Config.enableimages)
    except:
        __builtins__.chr = oldchr
        raise

    __builtins__.chr = oldchr

    layout.go(pdfout, meta, body, binaries, cfg.Config)


def convert(fn):
  if len(fn) < 5 or fn[-4:].lower() != '.fb2':
     return False, '<big><b>' + fn + ':<br>' + \
        ' ERROR: <br>The file needs to have an \'.fb2\' extension!</b></big>'

  pdffn = fn[:-4] + '.pdf'
  pdffn0 = pdffn
  if sys.platform == 'win32' and type(pdffn) == type(u''):
    pdffn0 = pdffn0.encode('cp1251')

  try:
    printt(fn, pdffn0, 'gui-config')
    return True, pdffn
  except:
    return False, '<big><b>' + fn + ':<br>' + \
           traceback.format_exc().replace('\n','<br>') + '</big></b>'


class MessagePopup(QtGui.QWidget):

    def __init__(self, parent=None):
        super(MessagePopup, self).__init__(parent)

        self.message = QtGui.QLabel()
        self.message.setFrameStyle(QtGui.QFrame.Sunken)
        self.message.setAlignment(QtCore.Qt.AlignCenter)
        self.message.setWordWrap(True)
        self.message.setAutoFillBackground(True)
        
        mainLayout = QtGui.QVBoxLayout()
        mainLayout.addWidget(self.message)
        self.setLayout(mainLayout)

        self.setWindowTitle(" ")
        #self.setMinimumSize(200, 200)
        self.textt = ''

    #def __del__(self):
    #    print 'x',self

    def sett(self, t):
        self.textt = t
        self.message.setText(t)
        QtGui.qApp.processEvents()
        

messages = []
popups = []

class Worker(QtCore.QThread):
    def __init__(self, parent = None):
        QtCore.QThread.__init__(self, parent)
        self.task = None
        self.outputname = []

    def __del__(self):
        self.wait()

    def run(self):
        for task in self.task:
            self.emit(QtCore.SIGNAL("popup"), '<b><big>Processing...</big></b>\n' + task[0] + '\n')
            status, oname = convert(task[0])
            self.outputname.append((status, oname))
            


class DropArea(QtGui.QLabel):

    changed = QtCore.pyqtSignal(QtCore.QMimeData)

    def __init__(self, parent = None):
        super(DropArea, self).__init__(parent)

        self.setMinimumSize(200, 200)
        self.setFrameStyle(QtGui.QFrame.Sunken | QtGui.QFrame.StyledPanel)
        self.setAlignment(QtCore.Qt.AlignCenter)
        self.setWordWrap(True)
        self.setAcceptDrops(True)
        self.setAutoFillBackground(True)
        
        self.thread = Worker()
        self.started = False
        self.clear()
        self.connect(self.thread, QtCore.SIGNAL("finished()"), self.updateDone)
        self.connect(self.thread, QtCore.SIGNAL("terminated()"), self.updateDone)
        self.connect(self.thread, QtCore.SIGNAL("popup"), self.makepopup)
        self.textt = ''

    def dragEnterEvent(self, event):
        #self.setText("<content>")
        self.setBackgroundRole(QtGui.QPalette.Highlight)
        event.acceptProposedAction()
        self.changed.emit(event.mimeData())

    def dragMoveEvent(self, event):
        event.acceptProposedAction()

    def dropEvent(self, event):
        mimeData = event.mimeData()

        url = None
        if mimeData.hasUrls():
            urls = []
            for url in mimeData.urls():
                url = url.path()
                if sys.platform == 'win32' and url[0] == '/':
                   url = url[1:]
                urls.append([url, None])

        self.setBackgroundRole(QtGui.QPalette.Dark)
        event.acceptProposedAction()

        if url and len(urls) > 0 and not self.started:
            self.started = True
            messages = []
            self.thread.task = urls
            self.thread.start()
        else:
            for x in xrange(3):
                QtGui.qApp.processEvents()
                self.setBackgroundRole(QtGui.QPalette.Light)
                QtGui.qApp.processEvents()
                QtCore.QThread.currentThread().msleep(100)
                self.setBackgroundRole(QtGui.QPalette.Dark)
                QtGui.qApp.processEvents()
                QtCore.QThread.currentThread().msleep(100)


    def dragLeaveEvent(self, event):
        self.clear()
        event.accept()

    def updateDone(self):
        self.started = False
        self.thread.task = None

        global popups
        popups = []

        tmp = []
        for status, oname in self.thread.outputname:
            if not status:
                msg = MessagePopup()
                msg.message.setText(oname)
                msg.show()
                QtGui.qApp.processEvents()
                messages.append(msg)
            else:
                tmp.append('<b>'+oname+'</b>')

        if len(tmp) > 0:
            msg = MessagePopup()
            msg.message.setText('<big><b>Done!</b></big><br>\n' +
                     'Generated files:<br>\n' +
                     '<br>'.join(tmp) + '<br><br>' +
                     'You can change the PDF generation parameters by editing ' +
                     '\'gui-config.py\'')
            msg.show()
            QtGui.qApp.processEvents()
            messages.append(msg)

        self.thread.outputname = []


    def makepopup(self, msgtext):
        global popups
        popups = []

        msg = MessagePopup()
        msg.message.setText(msgtext)
        msg.show()
        QtGui.qApp.processEvents()
        popups.append(msg)

    def clear(self):
        self.setText("<b><big>Drag-and-drop an fb2 file\nto convert to PDF!</big></b>")
        self.setBackgroundRole(QtGui.QPalette.Dark)
        self.changed.emit(None)


class DropSiteWindow(QtGui.QWidget):

    def __init__(self):
        super(DropSiteWindow, self).__init__()

        self.dropArea = DropArea()

        mainLayout = QtGui.QVBoxLayout()
        mainLayout.addWidget(self.dropArea)
        self.setLayout(mainLayout)

        self.setWindowTitle("fb2print one-button GUI")
        self.setMinimumSize(200, 200)


if __name__ == '__main__':

    import sys

    app = QtGui.QApplication(sys.argv)
    window = DropSiteWindow()
    window.show()
    sys.exit(app.exec_())


